#!/bin/bash

#------------------------------------------------------------------------------
# Wrapper around git for pushing and pulling repositories. Using the 'pass'
# password manager, it automatically inserts your token for authentication
# (prompting for your password if required).
#
# TODO:
# 	- Add autocompletion
# 	- Expand to handle passwords and usernames
# 	- Output a menu containing a password list, to allow for usage with an alias
# 	  or function (i.e "alias gpush='passgit -l $names && git push'")
# 	- Remove error messages when there is nothing to commit or when there is
# 	  conflicting changes
#
# Dependencies:
# 	- getopt
# 	- pass
# 	- expect
#------------------------------------------------------------------------------

shopt -s extglob

die() { echo "$(basename $0): $@" && exit 1 ;}

usage() {
	cat <<-USAGE
		Usage: passgit [push|pull]
		Automate pushing and pulling with the notes repository.

		Automatically prompts for password to 

		push	Pushes changes to git repository.
		pull	Pull changes to git repository.
		-p	Specify the password name
		-h	prints this help message
	USAGE
	exit ${1}
}

if [[ $(getopt -T ; echo $?) != 4 ]] ; then
	die "$(cat <<-GETOPT_ERR_MSG_END
		Your getopt is not the enhanced version. Please install a more recent version
		version of getopt.
	GETOPT_ERR_MSG_END
	)"
fi

git rev-parse --is-inside-work-tree &>/dev/null || die 'directory is not a git repo.'
command -v pass &>/dev/null || die 'pass command not found in PATH'

declare action passname
declare short='hn:' long='help,password-name:'
declare parsed=$(getopt -o $short -l $long -n $0 -- "${@}")

[[ $? != 0 ]] && die "Try $0 -h for more information"
eval set -- "$parsed"

while true ; do
	case "$1" in
		-n|--password-name) 
			passname="$2"
			shift 2
		;;
		--)
			shift
			break
		;;
		-h|--help) usage 0 ;;
		*) die 'Internal Error' ;;
	esac
done

[[ -z "$passname" ]] && die 'Please specify a password name with the -p option.'
[[ -z "$1" ]]  && die "Missing action"
[[ "$1" != @(push|pull) ]] && die "Invalid action '$1'"
action=$1

# Expect script to automate token insertion
expect <(cat <<-EOF
	set timeout -1
	set token [exec pass $passname]

	spawn git $action

	expect {
		"Already up to date." { expect eof }
		-re "Username for 'https://.*':" { 
			send "\${token}\r"
			exp_continue
		}
		-re "Password for 'https://.*':" { 
			send "\r"
			expect eof
		}
	}
	EOF
)
